package com.wind4869.bookmarks.actions;

import com.wind4869.bookmarks.Bookmark;
import com.wind4869.bookmarks.BookmarkManager;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.editor.Caret;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.LogicalPosition;
import com.intellij.openapi.editor.ScrollType;
import com.intellij.openapi.editor.actionSystem.EditorAction;
import com.intellij.openapi.editor.actionSystem.EditorActionHandler;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

abstract class GotoBookmarkActionBase extends EditorAction {
    protected GotoBookmarkActionBase(final boolean next) {
        super(new EditorActionHandler() {
            @Override
            public void doExecute(@NotNull Editor editor, @Nullable Caret caret, DataContext dataContext) {
                navigateToBookmark(dataContext, editor);
            }

            @Override
            public boolean isEnabledForCaret(@NotNull Editor editor, @NotNull Caret caret, DataContext dataContext) {
                return getBookmarkToGo(dataContext, editor) != null;
            }

            private void navigateToBookmark(DataContext dataContext, @NotNull final Editor editor) {
                final Bookmark bookmark = getBookmarkToGo(dataContext, editor);
                if (bookmark == null) return;

                int line = bookmark.getLine();
                if (line >= editor.getDocument().getLineCount()) return;
                if (line < 0) line = 0;

                LogicalPosition pos = new LogicalPosition(line, 0);
                editor.getSelectionModel().removeSelection();
                editor.getCaretModel().removeSecondaryCarets();
                editor.getCaretModel().moveToLogicalPosition(pos);
                editor.getScrollingModel().scrollTo(new LogicalPosition(line, 0), ScrollType.CENTER);
            }

            @Nullable
            private Bookmark getBookmarkToGo(DataContext dataContext, @NotNull Editor editor) {
                Project project = CommonDataKeys.PROJECT.getData(dataContext);
                if (project == null) return null;
                return BookmarkManager.getInstance(project).findLineBookmark(editor, true, next);
            }
        });
    }
}
